package com.edu.app.controller.fileuploader;

import com.edu.app.bean.core.SysFile;
import com.edu.app.bean.core.SysUser;
import com.edu.app.bean.oss.SysOssFile;
import com.edu.app.constant.ErrorConstant;
import com.edu.app.constant.SysMessage;
import com.edu.app.service.sys.core.SysFileService;
import com.edu.app.service.sys.core.SysUserService;
import com.edu.app.service.sys.plupload.PluploadService;
import com.edu.app.threadlocal.TenantContext;
import com.edu.app.util.ErrorUtil;
import com.edu.app.util.JWTUtil;
import com.edu.app.util.MsgUtil;
import com.edu.app.util.alioss.OssAccessor;
import com.edu.app.util.alioss.OssCallbackUtil;
import com.edu.app.util.alioss.OssConfig;
import com.edu.app.util.plupload.Plupload;

import com.google.gson.Gson;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

import static com.edu.app.constant.SysMessage.GET_POSTPOLICY_SUCCEED;

@RequestMapping(value = "/api/oss")
@RestController
public class FileUploaderController {
    @Autowired
    PluploadService pluploadService;

    @Autowired
    OssAccessor ossAccessor;

    @Autowired
    SysFileService sysFileService;

    @Autowired
    SysUserService sysUserService;

    @GetMapping(value = "/postpolicy")
    @RequiresAuthentication
    public Map<String,Object> getPostPolicy (@RequestHeader("Authorization") String token, HttpServletRequest request){

        try {
            String username = JWTUtil.getUsername(token);
            SysUser sysUser = sysUserService.getUserByName(username);
            StringBuffer callback = new StringBuffer();
            callback.append(request.getScheme());
            callback.append("://");
            callback.append(request.getServerName());
            callback.append(":");
            callback.append(request.getServerPort());
            callback.append(request.getContextPath());
            callback.append("/api/oss/ossfilerecord");
            //String path     = request.getContextPath();
            //String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

            Map<String, String> map = ossAccessor.getPostObjectPolicy(OssConfig.bucket,
                                                                            OssConfig.endpoint,
                                                                            OssConfig.EDUCRM_AccessKeyId,
                                                                            OssConfig.EDUCRM_AccessKeySecret,
                                                                            callback.toString(),
                                                                            sysUser.getTenant_id());
            return MsgUtil.retMap(GET_POSTPOLICY_SUCCEED, "postpolicy", map);

        }
        catch(UnsupportedEncodingException UnEE)
        {
            return ErrorUtil.retErrMsgMap(UnEE);
        }
    }


    private void response(HttpServletRequest request, HttpServletResponse response, String results, int status) throws IOException {
        String callbackFunName = request.getParameter("callback");
        response.addHeader("Content-Length", String.valueOf(results.length()));
        if (callbackFunName == null || callbackFunName.equalsIgnoreCase(""))
            response.getWriter().println(results);
        else
            response.getWriter().println(callbackFunName + "( " + results + " )");
        response.setStatus(status);
        response.flushBuffer();
    }

    @PostMapping(value="/ossfilerecord")
    public Map<String, Object> ossCallback(HttpServletRequest request,
                                          HttpServletResponse response
                                         )
    {
        Map<String,Object> map =  null;
        try {
            String ossCallbackBody = OssCallbackUtil.GetPostBody(request.getInputStream(), Integer.parseInt(request.getHeader("content-length")));
            boolean ret = OssCallbackUtil.VerifyOSSCallbackRequest(request, ossCallbackBody);


            System.out.println("verify result: " + ret);
            System.out.println("OSS Callback Body: " + ossCallbackBody);


            if(ret)
            {
                // 使用new方法
                Gson gson = new Gson();

                SysOssFile sysOssFile = gson.fromJson(ossCallbackBody, SysOssFile.class);
                String url = ossAccessor.geturl(sysOssFile.getFilename());

                SysFile sysFile = new SysFile();
                sysFile.initializeSystemColumns("ossUpload");
                sysFile.setFile_url(url);
                sysFile.setFile_size(sysOssFile.getSize());
                sysFile.setFile_mime_type(sysOssFile.getMimeType());
                sysFile.setTenant_id(sysOssFile.getTenant_id());

                TenantContext.setNeedTenantId(Boolean.FALSE);
                sysFileService.add(sysFile);
                TenantContext.setNeedTenantId(Boolean.TRUE);

                map = MsgUtil.retMap(SysMessage.UPLOAD_FILE_SUCCEED,"fileurl",url);
                map.put("Status","OK");
                map.put("fileId",sysFile.getId());

                response.setStatus(HttpServletResponse.SC_OK);
            }
            else
            {
                map = ErrorUtil.retErrMsg(ErrorConstant.UPLOAD_FILE_ERROR );
                map.put("Status","verdify not ok");

                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            }

            //if (ret)
            //{
            //    response(request, response, "{\"Status\":\"OK\"}", HttpServletResponse.SC_OK);
            //}
            //else
            //{
            //    response(request, response, "{\"Status\":\"verdify not ok\"}", HttpServletResponse.SC_BAD_REQUEST);
            //}

        }
        catch(IOException ioe)
        {
            map = ErrorUtil.retErrMsg(ErrorConstant.UPLOAD_FILE_ERROR );
            map.put("Status","verdify not ok");

            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);

        }
        return map;


    }



    /**Plupload文件上传处理方法*/
    @RequestMapping(value="/pluploadUpload")
    public Map<String,Object>  upload(Plupload plupload, HttpServletRequest request, HttpServletResponse response) {

        String FileDir = "pluploadDir";//文件保存的文件夹
        plupload.setRequest(request);//手动传入Plupload对象HttpServletRequest属性

        //int userId = ((User)request.getSession().getAttribute("user")).getUserId();

        //文件存储绝对路径,会是一个文件夹，项目相应Servlet容器下的"pluploadDir"文件夹，还会以用户唯一id作划分
        File dir = new File(request.getSession().getServletContext().getRealPath("/") + FileDir+"/");
        if(!dir.exists()){
            dir.mkdirs();//可创建多级目录，而mkdir()只能创建一级目录
        }
        //开始上传文件
        String url = pluploadService.upload(plupload, dir);
        Map<String,Object> map =   MsgUtil.retMap(SysMessage.UPLOAD_FILE_SUCCEED,"fileurl",url);

        return map;
    }


    /*@GetMapping(value="/ststoken")
    public  Map<String,Object> getSTStoken(HttpServletRequest request,
                            HttpServletResponse response
    )
    {
        try {
            StringBuffer callback = new StringBuffer();
            callback.append(request.getScheme());
            callback.append("://");
            callback.append(request.getServerName());
            callback.append(":");
            callback.append(request.getServerPort());
            callback.append(request.getContextPath());
            callback.append("/api/oss/ossfilerecord");
            //String path     = request.getContextPath();
            //String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";



            Map<String, String> map =  ossAccessor.getPostObjectPolicy(OssConfig.bucket,
                                                                        OssConfig.endpoint,
                                                                        OssConfig.EDUCRM_AccessKeyId,
                                                                        OssConfig.EDUCRM_AccessKeySecret,
                                                                        callback.toString());
            return MsgUtil.retMap(GET_POSTPOLICY_SUCCEED, "postpolicy", map);

        }
        catch(UnsupportedEncodingException UnEE)
        {
            return ErrorUtil.retErrMsgMap(UnEE);
        }
    }*/
}
